#include "stdafx.h"
#include "render/render.h"
#include "render/surface.h"
#include "SDL_gfxPrimitives.h"
#include "SDL_rotozoom.h"

int _aalineColor(SDL_Surface * dst, Sint16 x1, Sint16 y1, Sint16 x2, Sint16 y2, Uint32 color, int draw_endpoint);

namespace Render
{

inline void MySdlError()
{
	const char* error = SDL_GetError();
	DebugBreak();
}

inline SDL_Surface* GetSdlSurface(const SurfacePtr surface)
{
	return (SDL_Surface*) surface;
}

SDL_Rect* MakeSdlRect(const Rect* rect) {return (SDL_Rect*) rect;}

void SetClipRect(SurfacePtr surface,  const Rect* pRect)
{
	SDL_SetClipRect(GetSdlSurface(surface), MakeSdlRect(pRect));
}

void Clear(SurfacePtr surface, U32 colour)
{
	if (SDL_FillRect(GetSdlSurface(surface), NULL, colour) < 0)
		MySdlError();
}

void DrawLine(SurfacePtr surface, int x1, int y1, int x2, int y2, U32 rgba)
{
	if (_aalineColor(GetSdlSurface(surface), x1, y1, x2, y2, rgba, 0) < 0)
		MySdlError();
}

void DrawRect(SurfacePtr surface, int x1, int y1, int x2, int y2, U32 rgba)
{
	if (rectangleColor(GetSdlSurface(surface), x1, y1, x2, y2, rgba) < 0)
		MySdlError();
}

void DrawPixel(SurfacePtr surface, int x, int y, U32 rgba)
{
	if (pixelColor(GetSdlSurface(surface), x, y, rgba) < 0)
		MySdlError();
}

void FillRect(SurfacePtr surface, int x1, int y1, int x2, int y2, U32 rgba)
{
	if (boxColor(GetSdlSurface(surface), x1, y1, x2 - 1, y2 - 1, rgba) < 0)
		MySdlError();
}

void FillCircle(SurfacePtr surface, int x, int y, int r, U32 rgba)
{
	if (filledCircleColor(GetSdlSurface(surface), x, y, r, rgba) < 0)
		MySdlError();
}

void DrawCircle(SurfacePtr surface, int x, int y, int r, U32 rgba)
{
	if (circleColor(GetSdlSurface(surface), x, y, r, rgba) < 0)
		MySdlError();
}

void FillPolygon(SurfacePtr surface, const S16 x[], const S16 y[], int count, U32 rgba)
{
	if (filledPolygonColor(GetSdlSurface(surface), x, y, count, rgba) < 0)
		MySdlError();
}

void DrawSprite(SurfacePtr dst, const SurfacePtr src, int x, int y)
{
	SDL_Rect dest; 
	dest.x = x;
	dest.y = y;
	dest.w = GetSdlSurface(src)->w;
	dest.h = GetSdlSurface(src)->h;

	if (SDL_BlitSurface(GetSdlSurface(src), NULL, GetSdlSurface(dst), &dest) < 0)
		MySdlError();
}

void Blit(SurfacePtr dst, const SurfacePtr src, const Rect& dstRect, const Rect& srcRect)
{
	if (SDL_BlitSurface(GetSdlSurface(src), MakeSdlRect(&srcRect), GetSdlSurface(dst), MakeSdlRect(&dstRect)) < 0)
		MySdlError();
}

void RotoZoom(SurfacePtr dst, const SurfacePtr src, const Render::Rect& dstRect, const Render::Rect& srcRect, float rotation, float zoom)
{
	Render::Surface newSurface(Render::CreateSurface(srcRect.w, srcRect.h));
	SDL_SetAlpha(GetSdlSurface(src), 0, 0);

	Render::Rect newRect;

	newRect.x = 0;
	newRect.y = 0;
	newRect.w = srcRect.w;
	newRect.h = srcRect.h;
	Render::Blit(newSurface, src, newRect, srcRect);

	Render::Surface rotated((Surface_Raw*) rotozoomSurface(GetSdlSurface(newSurface), -rotation, zoom, SMOOTHING_OFF));

	newRect.w = GetSdlSurface(rotated)->w;
	newRect.h = GetSdlSurface(rotated)->h;

	Render::Rect adjustedDstRect = dstRect;

	adjustedDstRect.x = dstRect.x + (srcRect.w - newRect.w) / 2;
	adjustedDstRect.y = dstRect.y + (srcRect.h - newRect.h) / 2;

	Render::Blit(dst, rotated, adjustedDstRect, newRect);
	SDL_SetAlpha(GetSdlSurface(src), SDL_SRCALPHA, 0);
}

}